#ifndef MATMUL_SUB_UTILS_H_
#define MATMUL_SUB_UTILS_H_

#include "kernel_operator.h"
#include "kernel_tiling/kernel_tiling.h"
#include "lib/matmul_intf.h"

using namespace AscendC;

constexpr int32_t BUFFER_NUM = 2;
constexpr uint64_t SYNC_MODE2 = 2;
constexpr uint64_t CUSTOM_SYNC_AIV_AIC_FLAG = 4;
constexpr uint64_t CUSTOM_SYNC_AIC_AIV_FLAG = 5;
constexpr uint64_t SYNC_AIV_AIC_CONFIG =
    1 | (SYNC_MODE2 << 4) | (CUSTOM_SYNC_AIV_AIC_FLAG << 8);
constexpr uint64_t SYNC_AIC_AIV_CONFIG =
    1 | (SYNC_MODE2 << 4) | (CUSTOM_SYNC_AIC_AIV_FLAG << 8);
constexpr int32_t PIPELINE_NUM = 8;
constexpr uint32_t UB_BLOCK_UNIT_SIZE = 32;
constexpr uint32_t UB_BLOCK_DOUBLE_UNIT_SIZE = 64;

__aicore__ inline void WaitAiv() { wait_flag_dev(CUSTOM_SYNC_AIV_AIC_FLAG); }

__aicore__ inline void WaitAic() { wait_flag_dev(CUSTOM_SYNC_AIC_AIV_FLAG); }

__aicore__ inline void NotifyAiv() {
  ffts_cross_core_sync(PIPE_FIX, SYNC_AIC_AIV_CONFIG);
}

__aicore__ inline void NotifyAic() {
  ffts_cross_core_sync(PIPE_MTE2, SYNC_AIV_AIC_CONFIG);
}

template <typename T> __aicore__ inline T AlignUp(T a, T base) {
  return (a + base - 1) / base * base;
}

template <typename T>
__aicore__ inline void DataCopyPad2D(const LocalTensor<T> dst,
                                     const GlobalTensor<T> src, uint32_t dim1,
                                     uint32_t dim0, uint32_t fullDim0) {

  DataCopyExtParams params;
  params.blockCount = dim1;
  params.blockLen = dim0 * sizeof(T);
  params.srcStride = (fullDim0 - dim0) * sizeof(T);
  params.dstStride = Ceil(dim0 * sizeof(T), UB_BLOCK_DOUBLE_UNIT_SIZE) * 2 -
                     Ceil(dim0 * sizeof(T), UB_BLOCK_UNIT_SIZE);

  DataCopyPadExtParams<T> padParams;
  padParams.isPad = true;
  padParams.rightPadding = 0;
  padParams.leftPadding = 0;
  padParams.paddingValue = 0;
  DataCopyPad(dst, src, params, padParams);
}

template <typename T>
__aicore__ inline void DataCopyPad2D(const GlobalTensor<T> dst,
                                     const LocalTensor<T> src, uint32_t dim1,
                                     uint32_t dim0, uint32_t srcFullDim0,
                                     uint32_t dstFullDim0) {

  DataCopyExtParams params;
  params.blockCount = dim1;
  params.blockLen = dim0 * sizeof(T);
  params.srcStride = static_cast<uint32_t>((srcFullDim0 - dim0) * sizeof(T) /
                                           UB_BLOCK_UNIT_SIZE);
  params.dstStride = (dstFullDim0 - dim0) * sizeof(T);
  DataCopyPad(dst, src, params);
}







#endif  // MATMUL_SUB_UTILS_H_